#pragma once

namespace SD_Tools
{
	class SimpleMenu;
	class SimpleMenuTree;
	class SimpleMenuNode;

	enum SM_NodeType
	{
		SMNT_DUMMY,
		SMNT_TREE,
		SMNT_BOOL,
		SMNT_BYTE,
		SMNT_INT,
		SMNT_FLOAT,
		SMNT_UINT
	};

	enum SM_HandleType
	{
		SMHT_NONE,
		SMHT_BORDERED
	};

	enum SM_InputCode
	{
		SMIC_OPEN,
		SMIC_ESCAPE,
		SMIC_SWITCH,
		SMIC_LEFT,
		SMIC_RIGHT,
		SMIC_UP,
		SMIC_DOWN
	};

	enum SM_EventCode
	{
		SMEC_ERROR,
		SMEC_NODEINCREASED,
		SMEC_NODEDECREASED,
		SMEC_MENUOPENED,
		SMEC_MENUCLOSED,
		SMEC_TREEOPENED,
		SMEC_TREECLOSED,
		SMEC_NODEOVERFLOWHIGH,
		SMEC_NODEOVERFLOWLOW,
		SMEC_ONRESETA,
		SMEC_ONRESETB,
		SMEC_TREERESETA,
		SMEC_TREERESETB,
		SMEC_TEXTUREUPDATE,
		SMEC_TREETEXTUREUPDATE
	};

	struct SM_TreeColorTable
	{
		D3DCOLOR Background;
		D3DCOLOR Background2;
		D3DCOLOR BackgroundActive;
		D3DCOLOR BackgroundContinued;
		D3DCOLOR OutLines;
		D3DCOLOR OutLines2;
		D3DCOLOR Text;
		D3DCOLOR Text2;
	};

	struct SM_ColorTable
	{
		D3DCOLOR Background;
		D3DCOLOR Background2;
		D3DCOLOR OutLines;
		D3DCOLOR OutLines2;
		D3DCOLOR Text;
		D3DCOLOR Text2;
		SM_TreeColorTable TreeColor;
	};

	struct SM_TreeFontTable
	{
		bool FontsInitialized;
		bool LostDevice;
		bool ResetDevice;
		ID3DXFont* Font;
		ID3DXFont* Font2;
	};

	struct SM_FontTable
	{
		ID3DXFont* Font;
		ID3DXFont* Font2;
		SM_TreeFontTable TreeFont;
	};

	struct SM_TreeSizeTable
	{
		Vector2 ItemSize;
		Vector2 BorderSize;
		float NextOffset;
		int FontSize;
		int FontSize2;
		wchar_t* FontName;
		int FontWeight;
		int Font2Weight;
	};

	struct SM_SizeTable
	{
		Vector2 BorderSize;
		int FontSize;
		int FontSize2;
		wchar_t* FontName;
		int FontWeight;
		int Font2Weight;
		SM_TreeSizeTable TreeSize;
	};

	class SimpleMenu
	{
		private:
			Rectangle2 Position;

			SimpleMenuTree* Root;

			IDirect3DDevice9* Device;
			IDirect3DStateBlock9* StateBlock;
			IDirect3DTexture9* Texture;

			SM_ColorTable* ColorTable;
			SM_FontTable FontTable;
			SM_SizeTable* SizeTable;

			SimpleMenuTree* TreeUpdate;

			bool Visible;

		public:

		private:
			void init();
			void RecursiveOnResetA(SimpleMenuTree* Tree);
			void RecursiveOnResetB(SimpleMenuTree* Tree);
			void RecursiveOnResetC(SimpleMenuTree* Tree);
			void RecursiveInit(SimpleMenuTree* Tree);
			SimpleMenuTree* GetCurrentTree();

		public:
			SimpleMenu(IDirect3DDevice9* Device, Vector2 Position, int NumberOfRootItems, SM_ColorTable* ColorTable, SM_SizeTable* SizeTable, wchar_t* Caption);

			Rectangle2* GetPositionRect();
			IDirect3DDevice9* GetDevice();

			SimpleMenuTree* GetRoot();

			SM_ColorTable* GetColorTable();
			SM_FontTable* GetFontTable();
			SM_SizeTable* GetSizeTable();

			HRESULT CreateTexture();
			void UpdateTexture();

			void InitMenu();

			void OnResetA();
			void OnResetB();
			void OnResetC();

			void SetTreeUpdate(SimpleMenuTree* Tree);
			void Input(SM_InputCode InputCode);

			bool IsActive();

			void Render();
	};

	class SimpleMenuTree
	{
		friend class SimpleMenu;

	private:
		SimpleMenu* Parent;

		SimpleMenuNode** Items;
		int NumberOfItems;
		int MaxNumberOfItems;

		bool AllowOverflow;

		Rectangle2 Position;

		int SelectedItemIndex;
		int ContinuedItemIndex;

		wchar_t* Caption;

		SM_TreeColorTable* ColorTable;
		SM_TreeFontTable* FontTable;
		SM_TreeSizeTable* SizeTable;

		IDirect3DTexture9* Texture;
	public:
	private:
		void init();

		void SetParent(SimpleMenu* Parent);

		void SetItem(SimpleMenuNode* Item, int Index);

		void DeleteContinuedItemIndex();


	public:
		SimpleMenuTree(SimpleMenu* Parent, Vector2 Position, int NumberOfItems, wchar_t* Caption);

		SimpleMenuNode* AddItem(SM_NodeType Type, void* HandleValue, wchar_t* Caption, wchar_t* Comment, bool Formatted = false);
		SimpleMenuNode* AddBorderedItem(SM_NodeType Type, void* HandleValue, int LeftValue, int RightValue, wchar_t* Caption, wchar_t* Comment, bool Formatted = false);
		SimpleMenuNode* AddFloatItem(float* HandleValue, float StepSize, wchar_t* Caption, wchar_t* Comment, bool Formatted = false);
		SimpleMenuTree* AddTree(int NumberOfRootItems, wchar_t* Caption, wchar_t* Comment);

		SimpleMenu* GetParent();

		SimpleMenuNode** GetItems();
		int GetNumberOfItems();

		Rectangle2* GetPositionRect();

		SimpleMenuNode* GetSelectedItem();
		SimpleMenuNode* GetContinuedItem();

		int GetSelectedItemIndex();
		int GetContinuedItemIndex();

		wchar_t* GetCaption();
		IDirect3DTexture9* GetTexture();

		SM_TreeColorTable* GetColorTable();
		SM_TreeFontTable* GetFontTable();
		SM_TreeSizeTable* GetSizeTable();

		HRESULT CreateTexture();
		void UpdateTexture();

		void OnResetA();
		void OnResetB();
		void OnResetC();

		void InitTree();

		void Input(SM_InputCode InputCode);

		void Render();
	};


	class SimpleMenuNode
	{
		friend class SimpleMenuTree;
	private:
		SimpleMenuTree* Parent;

		SimpleMenuTree* Next;
		SM_NodeType NodeType;
		SM_HandleType HandleType;

		bool IsFormattedCaption;

		wchar_t* Caption;
		wchar_t* Comment;

		bool AllowOverflow; // Allow starting at Leftvalue when reached RightValue / Bufferend

		void* HandleValue; // Holds an pointer to the Value
		float StepSize; // float stepsize
		int LeftValue; // Holds LeftValue
		int RightValue; // Holds RightValue

	public:

	private:

		void init();

		void SetParent(SimpleMenuTree* Parent);

		void SetNext(SimpleMenuTree* Next);
		void SetNodeType(SM_NodeType NodeType);
		void SetHandleType(SM_HandleType HandleType);
		void SetCaption(wchar_t* Caption);
		void SetComment(wchar_t* Comment);

		void SetAllowOverflow(bool AllowOverflow);
		void SetFormattedCaption(bool IsFormattedCaption);

		void SetHandleValue(void* Value);
		void SetLeftValue(int LeftValue);
		void SetRightValue(int RightValue);
		void SetStepSize(float StepSize);

		void Increase();
		void Decrease();

	public:


		SimpleMenuNode(SimpleMenuTree* Parent, SM_NodeType NodeType, SM_HandleType HandleType, wchar_t* Caption, wchar_t* Comment, SimpleMenuTree* Next);

		SimpleMenuTree* GetParent();

		SimpleMenuTree* GetNext();
		SM_NodeType GetNodeType();
		SM_HandleType GetHandleType();

		bool IsFormatted();

		wchar_t* GetCaption();
		wchar_t* GetComment();

		bool IsOverflow();

		void* GetHandleValue();
		void GetHandleValue(void* Out);
		int GetIntHandleValue();

		int GetLeftValue();

		int GetRightValue();
	};

	//_____________________________________________________________________________________________________________________________________________________
	//_____________________________________________________________________________________________________________________________________________________
	//_____________________________________________________________________________________________________________________________________________________
	//_____________________________________________________________________________________________________________________________________________________

	void SimpleMenu::init()
	{
		memset(&this->Position, 0, sizeof(this->Position));

		this->Root = NULL;

		this->Device = NULL;
		this->StateBlock = NULL;
		this->Texture = NULL;

		this->Visible = false;

		this->TreeUpdate = NULL;

		this->ColorTable = NULL;
		this->SizeTable = NULL;
		memset(&this->FontTable, 0, sizeof(this->FontTable));
	}

	void SimpleMenu::RecursiveOnResetA( SimpleMenuTree* Tree )
	{
		Tree->OnResetA();
		for (int i = 0; i < Tree->GetNumberOfItems(); i++)
		{
			if (Tree->GetItems()[i]->GetNodeType() == SMNT_TREE)
			{
				RecursiveOnResetA(Tree->GetItems()[i]->GetNext());
			}
		}
	}

	void SimpleMenu::RecursiveOnResetB( SimpleMenuTree* Tree )
	{
		Tree->OnResetB();
		for (int i = 0; i < Tree->GetNumberOfItems(); i++)
		{
			if (Tree->GetItems()[i]->GetNodeType() == SMNT_TREE)
			{
				RecursiveOnResetB(Tree->GetItems()[i]->GetNext());
			}
		}
	}

	void SimpleMenu::RecursiveOnResetC( SimpleMenuTree* Tree )
	{
		Tree->OnResetC();
		for (int i = 0; i < Tree->GetNumberOfItems(); i++)
		{
			if (Tree->GetItems()[i]->GetNodeType() == SMNT_TREE)
			{
				RecursiveOnResetC(Tree->GetItems()[i]->GetNext());
			}
		}
	}

	void SimpleMenu::RecursiveInit( SimpleMenuTree* Tree )
	{
		Tree->InitTree();
		for (int i = 0; i < Tree->GetNumberOfItems(); i++)
		{
			if (Tree->GetItems()[i]->GetNodeType() == SMNT_TREE)
			{
				RecursiveInit(Tree->GetItems()[i]->GetNext());
			}
		}
	}

	SimpleMenuTree* SimpleMenu::GetCurrentTree()
	{
		SimpleMenuTree* ReturnTree = this->Root;

		while(ReturnTree->GetContinuedItemIndex() >= 0)
		{
			ReturnTree = ReturnTree->GetContinuedItem()->GetNext();
		}

		return ReturnTree;
	}

	SimpleMenu::SimpleMenu(IDirect3DDevice9* Device, Vector2 Position, int NumberOfRootItems, SM_ColorTable* ColorTable, SM_SizeTable* SizeTable, wchar_t* Caption)
	{
		init();
		this->Device = Device;
		this->ColorTable = ColorTable;
		this->SizeTable = SizeTable;
		this->Position.x = Position.x;
		this->Position.y = Position.y;
		Root = new SimpleMenuTree(this, Vector2(Position.x+this->SizeTable->BorderSize.x, Position.y+this->SizeTable->BorderSize.y), NumberOfRootItems, Caption);
		this->Position.w = Root->GetPositionRect()->w + this->SizeTable->BorderSize.x * 2;
		this->Position.h = Root->GetPositionRect()->h + this->SizeTable->BorderSize.y * 2;
	}

	Rectangle2* SimpleMenu::GetPositionRect()
	{
		return &this->Position;
	}

	IDirect3DDevice9* SimpleMenu::GetDevice()
	{
		return this->Device;
	}

	SimpleMenuTree* SimpleMenu::GetRoot()
	{
		return this->Root;
	}

	SM_ColorTable* SimpleMenu::GetColorTable()
	{
		return this->ColorTable;
	}

	SM_FontTable* SimpleMenu::GetFontTable()
	{
		return &this->FontTable;
	}

	SM_SizeTable* SimpleMenu::GetSizeTable()
	{
		return this->SizeTable;
	}

	HRESULT SimpleMenu::CreateTexture()
	{
		return SD_Tools::AbstractDraw::CreateTexture(this->Device, (UINT) this->Position.w+2, (UINT) this->Position.h+2, &this->Texture);
	}

	void SimpleMenu::UpdateTexture()
	{
		LPDIRECT3DSURFACE9 TempBackBuffer;
		int TriangleVertices = 0;
		int LineVertices = 0;

		Rectangle2 SaveRect = this->Position;

		this->Position.x = 0.0f;
		this->Position.y = 0.0f;

		SHAPEVERTEX* Buffer = AbstractDraw::AcquireShapeBuffer(AbstractDraw::CreateRoundedRectangle(0, Rectangle2(0.0f, 0.0f, this->Position.w, this->Position.h), this->SizeTable->BorderSize, this->ColorTable->Background));
		SHAPEVERTEX* Buffer2 = AbstractDraw::AcquireShapeBuffer(AbstractDraw::CreateOutlineOutRoundedRectangle(0, Rectangle2(0.0f, 0.0f, this->Position.w, this->Position.h), this->SizeTable->BorderSize, this->ColorTable->OutLines));

		TriangleVertices += AbstractDraw::CreateRoundedRectangle(Buffer, this->Position, this->SizeTable->BorderSize, this->ColorTable->Background);
		LineVertices += AbstractDraw::CreateOutlineOutRoundedRectangle(Buffer2, this->Position, this->SizeTable->BorderSize, this->ColorTable->OutLines);

		AbstractDraw::BeginTextureRender(this->Device, this->Texture, &TempBackBuffer);

		AbstractDraw::ClearRenderTarget(this->Device);

		AbstractDraw::DrawTriangleBuffer(this->Device, TriangleVertices, Buffer);

		AbstractDraw::DrawLineBuffer(this->Device, LineVertices, Buffer2);

		AbstractDraw::DrawText(this->FontTable.Font, NULL, Vector2(this->Position.x + this->Position.w/2, this->Position.y + this->SizeTable->BorderSize.y/2), this->ColorTable->Text, SD_Tools::SDDT_CENTER, L"M0g3lW3rkz3ug");

		AbstractDraw::EndTextureRender(this->Device, TempBackBuffer);

		AbstractDraw::ReleaseShapeBuffer(Buffer);
		AbstractDraw::ReleaseShapeBuffer(Buffer2);

		this->Position = SaveRect;
	}

	void SimpleMenu::InitMenu()
	{
		SD_Tools::AbstractDraw::PrepareStateBlock(this->Device, &this->StateBlock);

		SD_Tools::AbstractDraw::CreateFont_SD(this->Device, this->SizeTable->FontSize, this->SizeTable->FontWeight, false, this->SizeTable->FontName, &this->FontTable.Font);
		SD_Tools::AbstractDraw::CreateFont_SD(this->Device, this->SizeTable->FontSize2, this->SizeTable->Font2Weight, false, this->SizeTable->FontName, &this->FontTable.Font2);

		this->CreateTexture();

		SD_Tools::AbstractDraw::BeginStateBlock(this->Device, this->StateBlock, SD_Tools::ShapeFVF);

		this->UpdateTexture();

		RecursiveInit(this->Root);

		SD_Tools::AbstractDraw::EndStateBlock(this->StateBlock);
	}

	void SimpleMenu::OnResetA()
	{
		AbstractDraw::TextureResetA(this->Texture);
		AbstractDraw::StateBlockResetA(this->StateBlock);

		AbstractDraw::FontResetA(this->FontTable.Font);
		AbstractDraw::FontResetA(this->FontTable.Font2);

		RecursiveOnResetA(this->Root);
	}

	void SimpleMenu::OnResetB()
	{
		AbstractDraw::StateBlockResetB(this->Device, &this->StateBlock);
		AbstractDraw::TextureResetB(this->Device, &this->Texture);

		AbstractDraw::FontResetB(this->FontTable.Font);
		AbstractDraw::FontResetB(this->FontTable.Font2);

		SD_Tools::AbstractDraw::BeginStateBlock(this->Device, this->StateBlock, SD_Tools::ShapeFVF);

		this->CreateTexture();

		RecursiveOnResetB(this->Root);

		SD_Tools::AbstractDraw::EndStateBlock(this->StateBlock);
	}

	void SimpleMenu::OnResetC()
	{
		SD_Tools::AbstractDraw::BeginStateBlock(this->Device, this->StateBlock, SD_Tools::ShapeFVF);

		this->UpdateTexture();

		RecursiveOnResetC(this->Root);

		SD_Tools::AbstractDraw::EndStateBlock(this->StateBlock);
	}

	void SimpleMenu::SetTreeUpdate( SimpleMenuTree* Tree )
	{
		this->TreeUpdate = Tree;
	}


	void SimpleMenu::Input( SM_InputCode InputCode )
	{
		switch (InputCode)
		{
		case SMIC_OPEN:
			{
				this->Visible = true;
				break;
			}
		case SMIC_ESCAPE:
			{
				if (this->Root->GetContinuedItemIndex() >= 0)
				{
					SimpleMenuTree* Current = this->Root;
					SimpleMenuTree* Last = NULL;
					while (Current->GetContinuedItemIndex() >= 0)
					{
						Last = Current;
						Current = Current->GetContinuedItem()->GetNext();
					}
					Last->DeleteContinuedItemIndex();
					this->TreeUpdate = Last;
				}
				else
				{
					this->Visible = false;
				}
				break;
			}
		case SMIC_SWITCH:
			{
				this->Visible = !this->Visible;
				break;
			}
		case SMIC_LEFT:
		case SMIC_RIGHT:
		case SMIC_UP:
		case SMIC_DOWN:
			{
				this->Root->Input(InputCode);
				break;
			}
		}
	}

	bool SimpleMenu::IsActive()
	{
		return this->Visible;
	}

	void SimpleMenu::Render()
	{
		if (this->Visible)
		{
			TEXVERTEX TexBuffer[6];
			int NumberOfVertices;
			NumberOfVertices = AbstractDraw::CreateTextureRectangle(TexBuffer, this->Position);
			SHAPEVERTEX LineBuffer[8];

			AbstractDraw::BeginStateBlock(this->Device, this->StateBlock, ShapeFVF);

			if (this->TreeUpdate)
			{
				this->TreeUpdate->UpdateTexture();
				this->TreeUpdate = NULL;
			}

			AbstractDraw::EndStateBlock(this->StateBlock);


			AbstractDraw::BeginStateBlock(this->Device, this->StateBlock, TexFVF);

			AbstractDraw::SetTexture(this->Device, this->Texture);

			SD_Tools::AbstractDraw::DrawTextureBuffer(this->Device, NumberOfVertices, TexBuffer);

			SimpleMenuTree* Current = this->Root;
			SimpleMenuTree* Last;
			Current->Render();

			while(Current->GetContinuedItemIndex() >= 0)
			{
				Last = Current;
				Current = Current->GetContinuedItem()->GetNext();

				AbstractDraw::SetFVF(this->Device, ShapeFVF);
				AbstractDraw::SetTexture(this->Device, NULL);

				AbstractDraw::CreateLine(LineBuffer, Vector2(Last->GetPositionRect()->x + Last->GetSizeTable()->BorderSize.x, Last->GetPositionRect()->y + Last->GetSizeTable()->BorderSize.y*2 + Last->GetSizeTable()->ItemSize.y * (Last->GetContinuedItemIndex()+1) - 1.0f), Vector2(Current->Position.x, Current->Position.y), this->ColorTable->OutLines2);
				AbstractDraw::CreateLine(LineBuffer+2, Vector2(Last->GetPositionRect()->x + Last->GetSizeTable()->BorderSize.x + Last->GetSizeTable()->ItemSize.x, Last->GetPositionRect()->y + Last->GetSizeTable()->BorderSize.y*2 + Last->GetSizeTable()->ItemSize.y * (Last->GetContinuedItemIndex()+1) - 1.0f), Vector2(Current->Position.x+Current->Position.w, Current->Position.y), this->ColorTable->OutLines2);
				AbstractDraw::CreateLine(LineBuffer+4, Vector2(Last->GetPositionRect()->x + Last->GetSizeTable()->BorderSize.x + Last->GetSizeTable()->ItemSize.x, Last->GetPositionRect()->y + Last->GetSizeTable()->BorderSize.y*2 + Last->GetSizeTable()->ItemSize.y * (Last->GetContinuedItemIndex()+2) - 1.0f), Vector2(Current->Position.x+Current->Position.w, Current->Position.y+Current->Position.h), this->ColorTable->OutLines2);
				AbstractDraw::CreateLine(LineBuffer+6, Vector2(Last->GetPositionRect()->x + Last->GetSizeTable()->BorderSize.x, Last->GetPositionRect()->y + Last->GetSizeTable()->BorderSize.y*2 + Last->GetSizeTable()->ItemSize.y * (Last->GetContinuedItemIndex()+2) - 1.0f), Vector2(Current->Position.x, Current->Position.y+Current->Position.h), this->ColorTable->OutLines2);
				AbstractDraw::DrawLineBuffer(this->Device, 8, LineBuffer);

				AbstractDraw::SetFVF(this->Device, TexFVF);

				Current->Render();
			}

			AbstractDraw::SetTexture(this->Device, NULL);

			AbstractDraw::EndStateBlock(this->StateBlock);
		}
	}

	//_____________________________________________________________________________________________________________________________________________________
	//_____________________________________________________________________________________________________________________________________________________
	//_____________________________________________________________________________________________________________________________________________________
	//_____________________________________________________________________________________________________________________________________________________


	void SimpleMenuTree::init()
	{
		this->Parent = NULL;

		this->Items = NULL;
		this->NumberOfItems = 0;
		this->MaxNumberOfItems = 0;

		this->AllowOverflow = true;

		memset(&this->Position, 0, sizeof(this->Position));

		this->SelectedItemIndex = 0;
		this->ContinuedItemIndex = -1;

		this->Caption = NULL;

		this->ColorTable = NULL;
		this->SizeTable = NULL;
		this->FontTable = NULL;

		this->Texture = NULL;
	}

	void SimpleMenuTree::DeleteContinuedItemIndex()
	{
		this->ContinuedItemIndex = -1;
	}


	SimpleMenuTree::SimpleMenuTree( SimpleMenu* Parent, Vector2 Position, int NumberOfItems, wchar_t* Caption )
	{
		init();
		this->MaxNumberOfItems = NumberOfItems;
		this->Parent = Parent;

		this->Items = new SimpleMenuNode*[this->MaxNumberOfItems];

		this->Caption = new wchar_t[wcslen(Caption) + 1];
		wcscpy(this->Caption, Caption);

		this->ColorTable = &this->Parent->GetColorTable()->TreeColor;
		this->FontTable = &this->Parent->GetFontTable()->TreeFont;
		this->SizeTable = &this->Parent->GetSizeTable()->TreeSize;

		this->Position.w = this->SizeTable->ItemSize.x + this->SizeTable->BorderSize.x*2;
		this->Position.h = this->SizeTable->ItemSize.y * (this->MaxNumberOfItems+1) + this->SizeTable->BorderSize.y*3;
		//Rectangle2 TempRect = *this->Parent->GetPositionRect();
		this->Position.x = Position.x;
		this->Position.y = Position.y;
	}

	SimpleMenuNode* SimpleMenuTree::AddItem( SM_NodeType Type, void* HandleValue, wchar_t* Caption, wchar_t* Comment, bool Formatted /*= false*/ )
	{
		SimpleMenuNode* temp = NULL;
		if (this->NumberOfItems < this->MaxNumberOfItems)
		{
			this->Items[this->NumberOfItems] = new SimpleMenuNode(this, Type, SMHT_NONE, Caption, Comment, 0);
			temp = this->Items[this->NumberOfItems];
			temp->SetFormattedCaption(Formatted);
			temp->SetHandleValue(HandleValue);
			this->NumberOfItems++;
		}
		return temp;
	}

	SimpleMenuNode* SimpleMenuTree::AddBorderedItem( SM_NodeType Type, void* HandleValue, int LeftValue, int RightValue, wchar_t* Caption, wchar_t* Comment, bool Formatted /*= false*/ )
	{
		SimpleMenuNode* temp = NULL;
		if (this->NumberOfItems < this->MaxNumberOfItems)
		{
			this->Items[this->NumberOfItems] = new SimpleMenuNode(this, Type, SMHT_BORDERED, Caption, Comment, 0);
			temp = this->Items[this->NumberOfItems];
			temp->SetFormattedCaption(Formatted);
			temp->SetLeftValue(LeftValue);
			temp->SetRightValue(RightValue);
			temp->SetHandleValue(HandleValue);
			this->NumberOfItems++;
		}
		return temp;
	}

	SimpleMenuNode* SimpleMenuTree::AddFloatItem( float* HandleValue, float StepSize, wchar_t* Caption, wchar_t* Comment, bool Formatted /*= false*/ )
	{
		SimpleMenuNode* temp = NULL;
		if (this->NumberOfItems < this->MaxNumberOfItems)
		{
			this->Items[this->NumberOfItems] = new SimpleMenuNode(this, SMNT_FLOAT, SMHT_NONE, Caption, Comment, 0);
			temp = this->Items[this->NumberOfItems];
			temp->SetFormattedCaption(Formatted);
			temp->SetHandleValue(HandleValue);
			temp->SetStepSize(StepSize);
			this->NumberOfItems++;
		}
		return temp;
	}


	SimpleMenuTree* SimpleMenuTree::AddTree( int NumberOfRootItems, wchar_t* Caption, wchar_t* Comment )
	{
		SimpleMenuTree* temp = NULL;
		if (this->NumberOfItems < this->MaxNumberOfItems)
		{
			SimpleMenuTree* ReturnTree = new SimpleMenuTree(this->Parent, Vector2(this->Position.x + this->Position.w + this->SizeTable->NextOffset, this->Position.y), NumberOfRootItems, Caption);
			this->Items[this->NumberOfItems] = new SimpleMenuNode(this, SMNT_TREE, SMHT_NONE, Caption, Comment, ReturnTree);
			this->NumberOfItems++;
			temp = ReturnTree;
		}
		return temp;
	}


	SimpleMenu* SimpleMenuTree::GetParent()
	{
		return this->Parent;
	}

	SimpleMenuNode** SimpleMenuTree::GetItems()
	{
		return this->Items;
	}

	int SimpleMenuTree::GetNumberOfItems()
	{
		return this->NumberOfItems;
	}

	Rectangle2* SimpleMenuTree::GetPositionRect()
	{
		return &this->Position;
	}

	SimpleMenuNode* SimpleMenuTree::GetSelectedItem()
	{
		return this->Items[this->SelectedItemIndex];
	}

	SimpleMenuNode* SimpleMenuTree::GetContinuedItem()
	{
		return this->Items[this->ContinuedItemIndex];
	}


	int SimpleMenuTree::GetSelectedItemIndex()
	{
		return this->SelectedItemIndex;
	}

	int SimpleMenuTree::GetContinuedItemIndex()
	{
		return this->ContinuedItemIndex;
	}

	wchar_t* SimpleMenuTree::GetCaption()
	{
		return this->Caption;
	}

	IDirect3DTexture9* SimpleMenuTree::GetTexture()
	{
		return this->Texture;
	}

	SM_TreeColorTable* SimpleMenuTree::GetColorTable()
	{
		return this->ColorTable;
	}

	SM_TreeFontTable* SimpleMenuTree::GetFontTable()
	{
		return this->FontTable;
	}

	SM_TreeSizeTable* SimpleMenuTree::GetSizeTable()
	{
		return this->SizeTable;
	}

	HRESULT SimpleMenuTree::CreateTexture()
	{
		return AbstractDraw::CreateTexture(this->Parent->GetDevice(), (UINT) this->Position.w+2, (UINT) this->Position.h+2, &this->Texture);
	}

	void SimpleMenuTree::UpdateTexture()
	{
		LPDIRECT3DSURFACE9 TempBackBuffer;
		int TriangleVertices = 0;
		int LineVertices = 0;

		Rectangle2 SaveRect = this->Position;

		this->Position.x = 0.0f;
		this->Position.y = 0.0f;

		TriangleVertices += AbstractDraw::CreateRectangle(0, this->Position, this->ColorTable->Background);
		LineVertices += AbstractDraw::CreateOutlineRectangle(0, this->Position, this->ColorTable->OutLines);

		TriangleVertices += AbstractDraw::CreateRectangle(0, Rectangle2(this->Position.x, this->Position.y+this->SizeTable->BorderSize.y, this->Position.w, this->SizeTable->ItemSize.y), this->ColorTable->Background2);
		LineVertices += AbstractDraw::CreateOutlineRectangle(0, Rectangle2(this->Position.x, this->Position.y+this->SizeTable->BorderSize.y, this->Position.w, this->SizeTable->ItemSize.y), this->ColorTable->OutLines);

		for (int i = 0; i < this->NumberOfItems; i++)
		{
			TriangleVertices += AbstractDraw::CreateRectangle(0, Rectangle2(this->Position.x + this->SizeTable->BorderSize.x, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1), this->Position.w - this->SizeTable->BorderSize.x*2, this->Position.h - this->SizeTable->BorderSize.y*2), this->ColorTable->Background2);
			LineVertices += AbstractDraw::CreateOutlineRectangle(0, Rectangle2(this->Position.x + this->SizeTable->BorderSize.x, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1), this->Position.w - this->SizeTable->BorderSize.x*2, this->Position.h - this->SizeTable->BorderSize.y*2), this->ColorTable->OutLines2);
		}

		SHAPEVERTEX* Buffer = AbstractDraw::AcquireShapeBuffer(TriangleVertices);

		SHAPEVERTEX* Buffer2 = AbstractDraw::AcquireShapeBuffer(LineVertices);

		TriangleVertices = 0;
		LineVertices = 0;

		TriangleVertices += AbstractDraw::CreateRectangle(Buffer+TriangleVertices, this->Position, this->ColorTable->Background);
		LineVertices += AbstractDraw::CreateOutlineRectangle(Buffer2+LineVertices, this->Position, this->ColorTable->OutLines);

		TriangleVertices += AbstractDraw::CreateRectangle(Buffer+TriangleVertices, Rectangle2(this->Position.x, this->Position.y+this->SizeTable->BorderSize.y, this->Position.w, this->SizeTable->ItemSize.y), this->ColorTable->Background2);
		LineVertices += AbstractDraw::CreateOutlineRectangle(Buffer2+LineVertices, Rectangle2(this->Position.x, this->Position.y+this->SizeTable->BorderSize.y, this->Position.w, this->SizeTable->ItemSize.y), this->ColorTable->OutLines);

		for (int i = 0; i < this->NumberOfItems; i++)
		{
			if (i == this->ContinuedItemIndex)
			{
				TriangleVertices += AbstractDraw::CreateRectangle(Buffer+TriangleVertices, Rectangle2(this->Position.x + this->SizeTable->BorderSize.x, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1), this->SizeTable->ItemSize.x, this->SizeTable->ItemSize.y), this->ColorTable->BackgroundContinued);
				LineVertices += AbstractDraw::CreateOutlineRectangle(Buffer2+LineVertices, Rectangle2(this->Position.x + this->SizeTable->BorderSize.x, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1), this->SizeTable->ItemSize.x, this->SizeTable->ItemSize.y), this->ColorTable->OutLines2);
			}
			else if (i == this->SelectedItemIndex)
			{
				TriangleVertices += AbstractDraw::CreateRectangle(Buffer+TriangleVertices, Rectangle2(this->Position.x + this->SizeTable->BorderSize.x, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1), this->SizeTable->ItemSize.x, this->SizeTable->ItemSize.y), this->ColorTable->BackgroundActive);
				LineVertices += AbstractDraw::CreateOutlineRectangle(Buffer2+LineVertices, Rectangle2(this->Position.x + this->SizeTable->BorderSize.x, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1), this->SizeTable->ItemSize.x, this->SizeTable->ItemSize.y), this->ColorTable->OutLines2);
			}
			else
			{
				TriangleVertices += AbstractDraw::CreateRectangle(Buffer+TriangleVertices, Rectangle2(this->Position.x + this->SizeTable->BorderSize.x, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1), this->SizeTable->ItemSize.x, this->SizeTable->ItemSize.y), this->ColorTable->Background2);
				LineVertices += AbstractDraw::CreateOutlineRectangle(Buffer2+LineVertices, Rectangle2(this->Position.x + this->SizeTable->BorderSize.x, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1), this->SizeTable->ItemSize.x, this->SizeTable->ItemSize.y), this->ColorTable->OutLines2);
			}
		}

		AbstractDraw::BeginTextureRender(this->Parent->GetDevice(), this->Texture, &TempBackBuffer);

		AbstractDraw::ClearRenderTarget(this->Parent->GetDevice());

		AbstractDraw::DrawTriangleBuffer(this->Parent->GetDevice(), TriangleVertices, Buffer);

		AbstractDraw::DrawLineBuffer(this->Parent->GetDevice(), LineVertices, Buffer2);

		AbstractDraw::DrawText(this->FontTable->Font, NULL, Vector2(this->Position.x + this->Position.w/2, this->Position.y + this->SizeTable->BorderSize.y + this->SizeTable->ItemSize.y/2), this->ColorTable->Text, SD_Tools::SDDT_CENTER, this->Caption);

		for (int i = 0; i < this->NumberOfItems; i++)
		{
			if (this->Items[i]->IsFormatted())
			{
				switch (this->Items[i]->GetNodeType())
				{
				case SMNT_DUMMY:
				case SMNT_TREE:
					{
						AbstractDraw::DrawTextFormat(this->FontTable->Font, NULL, Vector2(this->Position.x + this->Position.w/2, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1) + this->SizeTable->ItemSize.y/2), this->ColorTable->Text, SD_Tools::SDDT_CENTER, this->Items[i]->GetCaption(), 0);
						break;
					}
				case SMNT_BOOL:
					{
						if (*(bool*)this->Items[i]->GetHandleValue())
						{
							AbstractDraw::DrawTextFormat(this->FontTable->Font, NULL, Vector2(this->Position.x + this->Position.w/2, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1) + this->SizeTable->ItemSize.y/2), this->ColorTable->Text, SD_Tools::SDDT_CENTER, this->Items[i]->GetCaption(), L"ON");
						}
						else
						{
							AbstractDraw::DrawTextFormat(this->FontTable->Font, NULL, Vector2(this->Position.x + this->Position.w/2, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1) + this->SizeTable->ItemSize.y/2), this->ColorTable->Text, SD_Tools::SDDT_CENTER, this->Items[i]->GetCaption(), L"OFF");
						}
						break;
					}
				case SMNT_BYTE:
					{
						AbstractDraw::DrawTextFormat(this->FontTable->Font, NULL, Vector2(this->Position.x + this->Position.w/2, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1) + this->SizeTable->ItemSize.y/2), this->ColorTable->Text, SD_Tools::SDDT_CENTER, this->Items[i]->GetCaption(), *(BYTE*)this->Items[i]->GetHandleValue());
						break;
					}
				case SMNT_INT:
					{
						AbstractDraw::DrawTextFormat(this->FontTable->Font, NULL, Vector2(this->Position.x + this->Position.w/2, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1) + this->SizeTable->ItemSize.y/2), this->ColorTable->Text, SD_Tools::SDDT_CENTER, this->Items[i]->GetCaption(), *(int*)this->Items[i]->GetHandleValue());
						break;
					}
				case SMNT_UINT:
					{
						AbstractDraw::DrawTextFormat(this->FontTable->Font, NULL, Vector2(this->Position.x + this->Position.w/2, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1) + this->SizeTable->ItemSize.y/2), this->ColorTable->Text, SD_Tools::SDDT_CENTER, this->Items[i]->GetCaption(), *(UINT*)this->Items[i]->GetHandleValue());
						break;
					}
				case SMNT_FLOAT:
					{
						AbstractDraw::DrawTextFormat(this->FontTable->Font, NULL, Vector2(this->Position.x + this->Position.w/2, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1) + this->SizeTable->ItemSize.y/2), this->ColorTable->Text, SD_Tools::SDDT_CENTER, this->Items[i]->GetCaption(), *(float*)this->Items[i]->GetHandleValue());
						break;
					}
				}
			}
			else
			{
				SD_Tools::AbstractDraw::DrawText(this->FontTable->Font, NULL, Vector2(this->Position.x + this->Position.w/2, this->Position.y + this->SizeTable->BorderSize.y*2 + this->SizeTable->ItemSize.y*(i+1) + this->SizeTable->ItemSize.y/2), this->ColorTable->Text, SD_Tools::SDDT_CENTER, this->Items[i]->GetCaption());
			}
		}

		SD_Tools::AbstractDraw::EndTextureRender(this->Parent->GetDevice(), TempBackBuffer);

		AbstractDraw::ReleaseShapeBuffer(Buffer);
		AbstractDraw::ReleaseShapeBuffer(Buffer2);

		this->Position = SaveRect;
	}

	void SimpleMenuTree::OnResetA()
	{
		SD_Tools::AbstractDraw::TextureResetA(this->Texture);
		if (!this->FontTable->LostDevice)
		{
			this->FontTable->ResetDevice = false;
			AbstractDraw::FontResetA(this->FontTable->Font);
			AbstractDraw::FontResetA(this->FontTable->Font2);
			this->FontTable->LostDevice = true;
		}
	}

	void SimpleMenuTree::OnResetB()
	{
		this->CreateTexture();
		if (!this->FontTable->ResetDevice)
		{
			this->FontTable->LostDevice = false;
			AbstractDraw::FontResetB(this->FontTable->Font);
			AbstractDraw::FontResetB(this->FontTable->Font2);
			this->FontTable->ResetDevice = true;
		}
	}

	void SimpleMenuTree::OnResetC()
	{
		this->UpdateTexture();
	}


	void SimpleMenuTree::InitTree()
	{
		if (!this->FontTable->FontsInitialized)
		{
			AbstractDraw::CreateFont_SD(this->Parent->GetDevice(), this->SizeTable->FontSize, this->SizeTable->FontWeight, false, this->SizeTable->FontName, &this->FontTable->Font);
			AbstractDraw::CreateFont_SD(this->Parent->GetDevice(), this->SizeTable->FontSize2, this->SizeTable->Font2Weight, false, this->SizeTable->FontName, &this->FontTable->Font2);
			this->FontTable->FontsInitialized = true;
		}

		this->CreateTexture();
		this->UpdateTexture();
	}

	void SimpleMenuTree::Input( SM_InputCode InputCode )
	{
		if (this->ContinuedItemIndex >= 0)
		{
			this->Items[this->ContinuedItemIndex]->GetNext()->Input(InputCode);
		}
		else
		{
			switch (InputCode)
			{
			case SMIC_LEFT:
				{
					if (this->Items[this->SelectedItemIndex]->GetNodeType() == SMNT_TREE)
					{
						this->ContinuedItemIndex = this->SelectedItemIndex;
					}
					else
					{
						this->Items[this->SelectedItemIndex]->Decrease();
					}
					break;
				}
			case SMIC_RIGHT:
				{
					if (this->Items[this->SelectedItemIndex]->GetNodeType() == SMNT_TREE)
					{
						this->ContinuedItemIndex = this->SelectedItemIndex;
					}
					else
					{
						this->Items[this->SelectedItemIndex]->Increase();
					}
					break;
				}
			case SMIC_UP:
				{
					if (this->SelectedItemIndex > 0)
					{
						this->SelectedItemIndex--;
					}
					else if (this->AllowOverflow)
					{
						this->SelectedItemIndex = this->NumberOfItems-1;
					}
					break;
				}
			case SMIC_DOWN:
				{
					if (this->SelectedItemIndex < this->NumberOfItems-1)
					{
						this->SelectedItemIndex++;
					}
					else if (this->AllowOverflow)
					{
						this->SelectedItemIndex = 0;
					}
					break;
				}
			}
			this->Parent->SetTreeUpdate(this);
		}
	}

	void SimpleMenuTree::Render()
	{
		TEXVERTEX TexBuffer[6];
		int NumberOfVertices;
		NumberOfVertices = AbstractDraw::CreateTextureRectangle(TexBuffer, this->Position);

		AbstractDraw::SetTexture(this->Parent->GetDevice(), this->Texture);

		SD_Tools::AbstractDraw::DrawTextureBuffer(this->Parent->GetDevice(), NumberOfVertices, TexBuffer);
	}

	//_____________________________________________________________________________________________________________________________________________________
	//_____________________________________________________________________________________________________________________________________________________
	//_____________________________________________________________________________________________________________________________________________________
	//_____________________________________________________________________________________________________________________________________________________


	void SimpleMenuNode::init()
	{
		this->Parent = NULL;

		this->Next = NULL;
		this->NodeType = SMNT_DUMMY;
		this->HandleType = SMHT_NONE;

		this->IsFormattedCaption = false;

		this->Caption = NULL;
		this->Comment = NULL;

		this->AllowOverflow = true; // Allow starting at Leftvalue when reached RightValue

		this->HandleValue = NULL; // Holds an pointer to the Value
		this->LeftValue = 0; // Holds LeftValue
		this->RightValue = 0; // Holds RightValue
	}

	void SimpleMenuNode::SetParent( SimpleMenuTree* Parent )
	{
		this->Parent = Parent;
	}

	void SimpleMenuNode::SetNext( SimpleMenuTree* Next )
	{
		this->Next = Next;
	}

	void SimpleMenuNode::SetNodeType( SM_NodeType NodeType )
	{
		this->NodeType = NodeType;
	}

	void SimpleMenuNode::SetHandleType( SM_HandleType HandleType )
	{
		this->HandleType = HandleType;
	}

	void SimpleMenuNode::SetCaption( wchar_t* Caption )
	{
		if (this->Caption)
		{
			delete[] this->Caption;
		}
		this->Caption = new wchar_t[wcslen(Caption) + 1];
		wcscpy(this->Caption, Caption);
	}

	void SimpleMenuNode::SetComment( wchar_t* Comment )
	{
		if (this->Comment)
		{
			delete[] this->Comment;
		}
		this->Comment = new wchar_t[wcslen(Comment) + 1];
		wcscpy(this->Comment, Comment);
	}

	void SimpleMenuNode::SetAllowOverflow( bool AllowOverflow )
	{
		this->AllowOverflow = AllowOverflow;
	}

	void SimpleMenuNode::SetFormattedCaption( bool IsFormattedCaption )
	{
		this->IsFormattedCaption = IsFormattedCaption;
	}

	void SimpleMenuNode::SetHandleValue( void* Value )
	{
		this->HandleValue = Value;
	}

	void SimpleMenuNode::SetLeftValue( int LeftValue )
	{
		this->LeftValue = LeftValue;
	}

	void SimpleMenuNode::SetRightValue( int RightValue )
	{
		this->RightValue = RightValue;
	}

	void SimpleMenuNode::SetStepSize( float StepSize )
	{
		this->StepSize = StepSize;
	}

	void SimpleMenuNode::Increase()
	{
		if (this->NodeType == SMNT_DUMMY || this->NodeType == SMNT_TREE)
		{
			return;
		}

		switch (this->HandleType)
		{
		case SMHT_BORDERED:
			{
				switch (this->NodeType)
				{
				case SMNT_BOOL:
					{
						*(bool*)this->HandleValue = !*(bool*)this->HandleValue;
						break;
					}
				case SMNT_BYTE:
					{
						if (*(BYTE*)this->HandleValue < this->RightValue)
						{
							*(BYTE*)this->HandleValue += 1;
						}
						else if (this->AllowOverflow)
						{
							*(BYTE*)this->HandleValue = (BYTE) this->LeftValue;
						}
						break;
					}
				case SMNT_INT:
					{
						if (*(int*)this->HandleValue < this->RightValue)
						{
							*(int*)this->HandleValue += 1;
						}
						else if (this->AllowOverflow)
						{
							*(int*)this->HandleValue = this->LeftValue;
						}
						break;
					}
				case SMNT_UINT:
					{
						if (*(UINT*)this->HandleValue < (UINT) this->RightValue)
						{
							*(UINT*)this->HandleValue += 1;
						}
						else if (this->AllowOverflow)
						{
							*(UINT*)this->HandleValue = this->LeftValue;
						}
						break;
					}
				case SMNT_FLOAT:
					{
						if (*(float*) this->HandleValue < (float) this->RightValue)
						{
							*(float*)this->HandleValue += this->StepSize;
						}
						else if (this->AllowOverflow)
						{
							*(float*)this->HandleValue = (float) this->LeftValue;
						}
						break;
					}
				}
				break;
			}
		case SMHT_NONE:
			{
				switch (this->NodeType)
				{
				case SMNT_BOOL:
					{
						*(bool*)this->HandleValue = !*(bool*)this->HandleValue;
						break;
					}
				case SMNT_BYTE:
					{
						*(BYTE*)this->HandleValue += 1;
						break;
					}
				case SMNT_INT:
					{
						*(int*)this->HandleValue += 1;
						break;
					}
				case SMNT_UINT:
					{
						*(UINT*)this->HandleValue += 1;
						break;
					}
				case SMNT_FLOAT:
					{
						*(float*)this->HandleValue += this->StepSize;
						break;
					}
				}
				break;
			}
		}
	}

	void SimpleMenuNode::Decrease()
	{
		if (this->NodeType == SMNT_DUMMY || this->NodeType == SMNT_TREE)
		{
			return;
		}

		switch (this->HandleType)
		{
		case SMHT_BORDERED:
			{
				switch (this->NodeType)
				{
				case SMNT_BOOL:
					{
						*(bool*)this->HandleValue = !*(bool*)this->HandleValue;
						break;
					}
				case SMNT_BYTE:
					{
						if (*(BYTE*)this->HandleValue > (BYTE) this->LeftValue)
						{
							*(BYTE*)this->HandleValue -= 1;
						}
						else if (this->AllowOverflow)
						{
							*(BYTE*)this->HandleValue = (BYTE) this->RightValue;
						}
						break;
					}
				case SMNT_INT:
					{
						if (*(int*)this->HandleValue > this->LeftValue)
						{
							*(int*)this->HandleValue -= 1;
						}
						else if (this->AllowOverflow)
						{
							*(int*)this->HandleValue = this->RightValue;
						}
						break;
					}
				case SMNT_UINT:
					{
						if (*(UINT*)this->HandleValue > (UINT) this->LeftValue)
						{
							*(UINT*)this->HandleValue -= 1;
						}
						else if (this->AllowOverflow)
						{
							*(UINT*)this->HandleValue = this->RightValue;
						}
						break;
					}
				case SMNT_FLOAT:
					{
						if (*(float*) this->HandleValue > (float) this->LeftValue)
						{
							*(float*)this->HandleValue -= this->StepSize;
						}
						else if (this->AllowOverflow)
						{
							*(float*)this->HandleValue = (float) this->RightValue;
						}
						break;
					}
				}
				break;
			}
		case SMHT_NONE:
			{
				switch (this->NodeType)
				{
				case SMNT_BOOL:
					{
						*(bool*)this->HandleValue = !*(bool*)this->HandleValue;
						break;
					}
				case SMNT_BYTE:
					{
						*(BYTE*)this->HandleValue -= 1;
						break;
					}
				case SMNT_INT:
					{
						*(int*)this->HandleValue -= 1;
						break;
					}
				case SMNT_UINT:
					{
						*(UINT*)this->HandleValue -= 1;
						break;
					}
				case SMNT_FLOAT:
					{
						*(float*)this->HandleValue -= this->StepSize;
						break;
					}
				}
				break;
			}
		}
	}


	SimpleMenuNode::SimpleMenuNode(SimpleMenuTree* Parent, SM_NodeType NodeType, SM_HandleType HandleType, wchar_t* Caption, wchar_t* Comment, SimpleMenuTree* Next)
	{
		init();
		this->NodeType = NodeType;
		this->HandleType = HandleType;
		this->Next = Next;
		this->Parent = Parent;

		this->Caption = new wchar_t[wcslen(Caption)+1];
		wcscpy(this->Caption, Caption);
		this->Comment = new wchar_t[wcslen(Comment)+1];
		wcscpy(this->Comment, Comment);

	}

	SimpleMenuTree* SimpleMenuNode::GetParent()
	{
		return this->Parent;
	}

	SimpleMenuTree* SimpleMenuNode::GetNext()
	{
		return this->Next;
	}

	SD_Tools::SM_NodeType SimpleMenuNode::GetNodeType()
	{
		return this->NodeType;
	}

	SD_Tools::SM_HandleType SimpleMenuNode::GetHandleType()
	{
		return this->HandleType;
	}

	bool SimpleMenuNode::IsFormatted()
	{
		return this->IsFormattedCaption;
	}

	wchar_t* SimpleMenuNode::GetCaption()
	{
		return this->Caption;
	}

	wchar_t* SimpleMenuNode::GetComment()
	{
		return this->Comment;
	}

	bool SimpleMenuNode::IsOverflow()
	{
		return this->AllowOverflow;
	}

	void* SimpleMenuNode::GetHandleValue()
	{
		return this->HandleValue;
	}

	void SimpleMenuNode::GetHandleValue( void* Out )
	{
		switch(this->HandleType)
		{
		case SMNT_DUMMY:
		case SMNT_TREE:
			*(int*)Out = 0;
			break;
		case SMNT_BOOL:
			*(bool*)Out = *(bool*)this->HandleValue;
			break;
		case SMNT_BYTE:
			*(BYTE*)Out = *(BYTE*)this->HandleValue;
			break;
		case SMNT_INT:
			*(int*)Out = *(int*)this->HandleValue;
			break;
		case SMNT_UINT:
			*(UINT*)Out = *(UINT*)this->HandleValue;
			break;
		case SMNT_FLOAT:
			*(float*)Out = *(float*)this->HandleValue;
			break;
		}
	}

	int SimpleMenuNode::GetIntHandleValue()
	{
		return *(int*)this->HandleValue;
	}

	int SimpleMenuNode::GetLeftValue()
	{
		return this->LeftValue;
	}

	int SimpleMenuNode::GetRightValue()
	{
		return this->RightValue;
	}

};
































